﻿using AutoMapper;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using YaAppoint.Appointments.Schedules;
using YaAppoint.Common;
using YaAppoint.Response;

namespace YaAppoint.Devices
{
    [RemoteService(isEnabled: false)]
    public class DeviceAppService(IRepository<Department, Guid> departmentRepository,
                                  IRepository<Device, Guid> deviceRepository,
                                  IRepository<DeviceType, Guid> deviceTypeRepository,
                                  IRepository<Schedule,Guid> scheduleRepository,
                                  IRepository<Room, Guid> roomRepository,
                                  AsyncQueryableExecuter queryableExcuter,
                                  IConfiguration configuration,
                                  ICommonAppService commonAppService,
                                  IMapper mapper) : ApplicationService, IDeviceAppService, ITransientDependency
    {
        private readonly IRepository<Department, Guid> _departmentRepository = departmentRepository;
        private readonly IRepository<Device, Guid> _deviceRepository = deviceRepository;
        private readonly IRepository<DeviceType, Guid> _deviceTypeRepository = deviceTypeRepository;
        private readonly IRepository<Room, Guid> _roomRepository = roomRepository;
        private readonly IRepository<Schedule, Guid> _scheduleRepository= scheduleRepository;
        private readonly AsyncQueryableExecuter _queryableExcuter = queryableExcuter;
        private readonly IConfiguration _configuration = configuration;
        private readonly ICommonAppService _commonAppService = commonAppService;
        private readonly IMapper _mapper = mapper;


        /// <summary>
        /// 加载Tree数据
        /// </summary>
        public async Task<BackJson> GetTreeData(Guid? depId)
        {
            var query = await _departmentRepository.GetQueryableAsync();

            if (depId != null)
            {
                query = query.Where(x => x.Id == depId);
            }
            var list = await _queryableExcuter.ToListAsync(query);
            var data = new
            {
                name = _configuration["InstitutionName"],
                id = 1,
                icon = "fa fa-hospital",
                children = list.Select(x => new
                {
                    name = x.Name,
                    id = x.Id,
                    icon = "fa fa-building",
                    children = x.Rooms!.Select(room => new
                    {
                        name = room.Name,
                        id = room.Id,
                        icon = "fa fa-display-medical"
                    })
                })
            };

            var res = new List<object>();
            res.Add(data);

            return new BackJson()
            {
                code = 0,
                data = res
            };
        }

        /// <summary>
        /// 获取科室设备类型
        /// </summary>
        public async Task<BackJson> GetDeviceTypeOptions(Guid depId)
        {
            var department = await _departmentRepository.FirstOrDefaultAsync(x => x.Id == depId);
            if (department == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceTypeNotExist);
            }
            var list = department.DeviceTypes!.Select(dt => new
            {
                value = dt.Id,
                label = dt.Name
            });
            return new BackJson()
            {
                code = 0,
                data = list
            };
        }

        /// <summary>
        /// 获取状态选项
        /// </summary>
        public BackJson LoadStatusOptions()
        {
            var data = new List<object>();
            foreach (var val in Enum.GetValues(typeof(DeviceStatus)))
            {
                var option = new
                {
                    label = _commonAppService.GetEnumValueDescription(val),
                    value = Convert.ToInt32(val)
                };

                data.Add(option);
            }
            return new BackJson()
            {
                code = 0,
                data = data
            };
        }

        /// <summary>
        /// 获取诊室下检查设备
        /// </summary>
        public async Task<BackJson> GetRoomDevicesAsync(Guid roomId)
        {
            var list = await _deviceRepository.GetListAsync(x => x.RoomId == roomId);
            return new BackJson()
            {
                code = 0,
                data = _mapper.Map<List<Device>, List<DeviceDto>>(list)
            };
        }

        /// <summary>
        /// 获取设备详情
        /// </summary>
        public async Task<BackJson> GetDetailAsync(Guid id)
        {
            var device = await _deviceRepository.FirstOrDefaultAsync(x => x.Id == id);
            if (device == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceNotExist);
            }
            return new BackJson()
            {
                code = 0,
                data = _mapper.Map<Device, DeviceDto>(device)
            };
        }

        /// <summary>
        /// 提交创建
        /// </summary>
        public async Task<BackJson> SubmitCreate(DeviceDto dto, Guid roomId)
        {
            var device = _mapper.Map<DeviceDto, Device>(dto);
            var deviceType = await _deviceTypeRepository.FirstOrDefaultAsync(x => x.Id == dto.DeviceTypeId);
            if (deviceType == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceTypeNotExist);
            }
            device.DeviceType = deviceType;
            var room = await _roomRepository.FirstOrDefaultAsync(x => x.Id == roomId);
            if (room == null)
            {
                throw new BusinessException(CustomErrorCodes.RoomNotExist);
            }
            device.RoomId = roomId;
            var department = await _departmentRepository.GetAsync(x=>x.Id==room.DepartmentId);
            device.DepartmentId = department.Id;
            await _deviceRepository.InsertAsync(device);
            return new BackJson()
            {
                code = 0,
                msg = "保存成功。"
            };
        }

        /// <summary>
        /// 提交编辑
        /// </summary>
        public async Task<BackJson> SubmitEdit(DeviceDto dto, Guid roomId)
        {
            var device = await _deviceRepository.FirstOrDefaultAsync(x => x.Id == dto.Id);
            if (device == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceNotExist);
            }
            device.Name = dto.Name;
            var deviceType = await _deviceTypeRepository.FirstOrDefaultAsync(x => x.Id == dto.DeviceTypeId);
            if (deviceType == null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceTypeNotExist);
            }
            var room = await _roomRepository.FirstOrDefaultAsync(x => x.Id == roomId);
            if (room == null)
            {
                throw new BusinessException(CustomErrorCodes.RoomNotExist);
            }
            device.DeviceTypeId = dto.DeviceTypeId;
            device.DeviceType = deviceType;
            device.Code = dto.Code;
            device.OuterCode = dto.OuterCode;
            device.Manufacturer = dto.Manufacturer;
            device.Model = dto.Model;
            device.AeTitle = dto.AeTitle;
            device.Status = dto.Status;
            device.ScheduleId = dto.ScheduleId;
            device.IsActive = dto.IsActive;

            await _deviceRepository.UpdateAsync(device);
            return new BackJson()
            {
                code = 0,
                msg = "保存成功。"
            };
        }

        /// <summary>
        /// 删除检查设备
        /// </summary>
        public async Task<BackJson> DeleteAsync(Guid id)
        {
            await _deviceRepository.DeleteAsync(id);
            return new BackJson()
            {
                code = 0,
                msg = "已删除。"
            };
        }

        /// <summary>
        /// 获取设备排班计划选项
        /// </summary>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        public async Task<BackJson> GetScheduleOptions(Guid deviceId)
        {
            var device = await _deviceRepository.FirstOrDefaultAsync(x => x.Id == deviceId);
            if (device==null)
            {
                throw new BusinessException(CustomErrorCodes.DeviceNotExist);
            }
            var scheduleList = await _scheduleRepository.GetListAsync(x => x.DepartmentId == device.DepartmentId && x.DeviceTypeId == device.DeviceTypeId && x.IsActive);
            return new BackJson()
            {
                code = 0,
                data = scheduleList.Select(x => new { value = x.Id, label = x.Name })
            };
        }
    }
}
